from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtSql import *
from math import *
import Ui_transaksiEdit
import utility
import pelangganSrc

ID_TRANSAKSI, URUT, NO_BUKTI, TEMPAT_TRANS,  JUMLAH,  STATUS = range(6)

class TransaksiEdit(QDialog, Ui_transaksiEdit.Ui_transaksiEditDlg):
  StyleSheet = """
QLineEdit[mandatory="true"] {
    background-color: rgb(255, 255, 127);
    color: darkblue;
}
"""
  def __init__(self, dbConn, tipe, dataGlob, parent=None):
        super(TransaksiEdit, self).__init__(parent)
        self.setupUi(self)
        self.db = dbConn
        self.tipe = tipe
        self.dataGlob = dataGlob
        self.util = utility.Utility(self.db)
        self.initData()
        self.tipeKartu.setEnabled(False)
        
        self.mastModel = QSqlTableModel(self)
        self.mastModel.setTable("transaksi")
        self.mastModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        
        self.detModel = QSqlTableModel(self)
        self.detModel.setTable("transaksi_det")
        self.detModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.detModel.setFilter("id_transaksi = '"+self.tipe+"'")
        self.detModel.setHeaderData(ID_TRANSAKSI, Qt.Horizontal, QVariant("ID"))
        self.detModel.setHeaderData(URUT, Qt.Horizontal, QVariant("Urut"))
        self.detModel.setHeaderData(NO_BUKTI, Qt.Horizontal, QVariant("No Bukti"))
        self.detModel.setHeaderData(TEMPAT_TRANS, Qt.Horizontal, QVariant("Toko"))
        self.detModel.setHeaderData(JUMLAH, Qt.Horizontal, QVariant("Jumlah (Rp)"))
        self.detModel.setHeaderData(STATUS, Qt.Horizontal, QVariant("Status"))
        self.connect(self.detModel, SIGNAL("dataChanged(QModelIndex,QModelIndex)"), self.hitungTotal)
        self.detModel.select()
        
        self.detail.setModel(self.detModel)
        self.detail.setItemDelegate(DetailDelegate(self))
        self.detail.setSelectionMode(QTableView.SingleSelection)
        self.detail.setSelectionBehavior(QTableView.SelectRows)
        self.detail.setColumnHidden(ID_TRANSAKSI, True)
        self.detail.setColumnHidden(URUT, True)
        self.detail.setColumnHidden(STATUS, True)
        self.detail.setColumnWidth(NO_BUKTI, 200)
        self.detail.setColumnWidth(TEMPAT_TRANS, 300)
        self.detail.setColumnWidth(JUMLAH, 200)
        
        self.idModel = QSqlTableModel(self)
        self.idModel.setTable("no_akhir")
        self.idModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        
        self.urut = 0
        if self.tipe != "add":
            query = QSqlQuery(self.db)
            query.exec_("select max(urut) from transaksi_det where id_transaksi = '"+self.tipe+"'")
            while query.next():
                self.urut = query.value(0).toInt()[0]
                
        self.nama.setProperty("mandatory", QVariant(True))
        self.setStyleSheet(TransaksiEdit.StyleSheet)

  @pyqtSignature("")
  def on_simpan_clicked(self):
      if self.idTrans.text() == "":
          if self.tambahData():
              self.close()
          else:
              QMessageBox.warning(self, "Transaksi","Tidak berhasil menambah data.")
      else:
          if self.updateData():
              self.close()
          else:
              QMessageBox.warning(self, "Pelanggan","Data tidak berhasil disimpan.")

  @pyqtSignature("")
  def on_batal_clicked(self):
      self.close()

  @pyqtSignature("")
  def on_tambahDet_clicked(self):
#      self.detModel.submit()
      self.urut += 1
      if self.idTrans.text() == "":
          if not self.tambahData():
              QMessageBox.warning(self, "Transaksi","Tidak berhasil menambah data.")
              return
          self.detModel.setFilter("id_transaksi = '"+self.idTrans.text()+"'")
          self.detModel.select()
      QSqlDatabase.database().transaction()
      row = self.detModel.rowCount()
      self.detModel.insertRow(row)
      self.detModel.setData(self.detModel.index(row, ID_TRANSAKSI), QVariant(self.idTrans.text()))
      self.detModel.setData(self.detModel.index(row, URUT), QVariant(self.urut))
      self.detModel.setData(self.detModel.index(row, STATUS), QVariant("0"))
      self.detModel.submitAll()
      QSqlDatabase.database().commit()
      index = self.detModel.index(row, NO_BUKTI)
      self.detail.setCurrentIndex(index)
      self.detail.edit(index)

  @pyqtSignature("")
  def on_hapusDet_clicked(self):
      index = self.detail.currentIndex()
      if not index.isValid():
          return
      record = self.detModel.record(index.row())
      kwit = record.value(NO_BUKTI).toString()
      toko = record.value(TEMPAT_TRANS).toString()
      if QMessageBox.question(self, "Detail Transaksi Data", QString("Hapus %1 dari %2?") .arg(kwit).arg(toko), QMessageBox.Yes|QMessageBox.No) == QMessageBox.No:
          return
      self.detModel.removeRow(index.row())
      self.detModel.submitAll()


  @pyqtSignature("")
  def on_cariBtn_clicked(self):
      form = pelangganSrc.PelangganSrc(self.db, self)
      if form.exec_():
          id = form.getID()
          self.idPlg.setText(id)
          query = QSqlQuery(self.db)
          query.exec_("select id_pelanggan, kode_pelanggan, nama, no_kartu, alamat1, telp1 from pelanggan where id_pelanggan = '"+id+"'")
          query.next()
          self.nama.setText(unicode(query.value(2).toString()))
          self.noMmc.setText(unicode(query.value(3).toString()))
          self.telp.setText(unicode(query.value(5).toString()))
          self.alamat.setText(unicode(query.value(4).toString()))
          
  @pyqtSignature("")
  def on_noKartu_editingFinished(self):
      query = QSqlQuery()
      query.exec_("select count(*) from cb_noawal where no_awal = '"+self.noKartu.text()+"'")
      query.next()
      kartuCIB = query.value(0).toInt()[0]
      if kartuCIB > 0:
          self.tipeKartu.setCurrentIndex(1)
      else:
          self.tipeKartu.setCurrentIndex(0)

  def tambahData(self):
      if not self.validasi():
          QMessageBox.warning(self, "Transaksi","Data yang diinput tidak valid / Kolom kosong.")
          return
      idBaru = self.idBaru()
      self.idTrans.setText(idBaru)
      self.noDok.setText(self.dokBaru())
#      self.auditTime.setDateTime(QDateTime.currentDateTime())
      hari = self.util.getServerToday()
      self.auditTime.setDateTime(hari)
      tgl = hari.date().toString("yyyy-MM-dd")
      self.mastModel.setFilter("tgl_trans = '"+tgl+"'")
      self.mastModel.select()     
      QSqlDatabase.database().transaction()
      if not self.mastModel.insertRow(0):
          return
      self.mastModel.setData(self.mastModel.index(0, 0), QVariant(self.idTrans.text()))
      self.mastModel.setData(self.mastModel.index(0, 1), QVariant(self.idPlg.text()))
      self.mastModel.setData(self.mastModel.index(0, 2), QVariant(self.noDok.text()))
      self.mastModel.setData(self.mastModel.index(0, 3), QVariant(self.tglDok.date()))
      self.mastModel.setData(self.mastModel.index(0, 4), QVariant(self.disetor.text()))
      self.mastModel.setData(self.mastModel.index(0, 5), QVariant(self.totalRp.text()))
      self.mastModel.setData(self.mastModel.index(0, 6), QVariant(self.poin.text()))
      self.mastModel.setData(self.mastModel.index(0, 7), QVariant(self.ket.text()))
      self.mastModel.setData(self.mastModel.index(0, 8), QVariant(self.auditUser.text()))
      self.mastModel.setData(self.mastModel.index(0, 9), QVariant(hari))
      self.mastModel.setData(self.mastModel.index(0, 10), QVariant("0"))
      self.mastModel.setData(self.mastModel.index(0, 11), QVariant(self.tipeKartu.currentText()))
      self.mastModel.setData(self.mastModel.index(0, 12), QVariant(self.noKartu.text()))
      self.mastModel.setData(self.mastModel.index(0, 13), QVariant(self.jenisToko.currentText()))
      if not self.mastModel.submitAll():
          return
      if not QSqlDatabase.database().commit():
          return
      self.tipe = idBaru
      return True
      
#      qIns.prepare("INSERT INTO transaksi (id_transaksi, id_pelanggan, no_trans, tgl_trans, disetor_oleh, total_rp, poin, ket, audit_user, audit_waktu, status, cc_tipe, no_cc, spec_store ) VALUES (:id_transaksi, :id_pelanggan, :no_trans, :tgl_trans, :disetor_oleh, :total_rp, :poin, :ket, :audit_user, :audit_waktu, :status, :cc_tipe, :no_cc, :spec_store)")

  def updateData(self):
      if not self.validasi():          
          return
      self.detModel.submitAll()
      self.hitungTotal()
      self.mastModel.setFilter("id_transaksi = '"+self.tipe+"'")
      self.mastModel.select()
      QSqlDatabase.database().transaction()
      self.mastModel.setData(self.mastModel.index(0, 3), QVariant(self.tglDok.date()))
      self.mastModel.setData(self.mastModel.index(0, 4), QVariant(self.disetor.text()))
      self.mastModel.setData(self.mastModel.index(0, 5), QVariant(self.totalRp.text()))
      self.mastModel.setData(self.mastModel.index(0, 6), QVariant(self.poin.text()))
      self.mastModel.setData(self.mastModel.index(0, 7), QVariant(self.ket.text()))
      self.mastModel.setData(self.mastModel.index(0, 10), QVariant("0"))
      self.mastModel.setData(self.mastModel.index(0, 11), QVariant(self.tipeKartu.currentText()))
      self.mastModel.setData(self.mastModel.index(0, 12), QVariant(self.noKartu.text()))
      self.mastModel.setData(self.mastModel.index(0, 13), QVariant(self.jenisToko.currentText()))
      if not self.mastModel.submitAll():
          return
      if not QSqlDatabase.database().commit():
          return
      return True
#      self.detModel.submitAll()

  def initData(self):
      hari = self.util.getServerToday()
      self.tglDok.setDate(hari.date())
      self.auditTime.setDateTime(hari)
      self.auditUser.setText(self.dataGlob["nama"])
      if self.tipe != "add":
          query = QSqlQuery(self.db)          
          qStr = "select t.id_transaksi, t.id_pelanggan, t.no_trans, t.tgl_trans, t.disetor_oleh, t.total_rp, t.poin, t.ket, t.audit_user, t.audit_waktu, t.status, t.cc_tipe, t.no_cc, t.spec_store, p.nama, p.no_kartu, p.telp1, p.alamat1  from transaksi t left outer join pelanggan p on p.id_pelanggan = t.id_pelanggan where t.id_transaksi = '"+self.tipe+"'"
          query.exec_(qStr)
          query.next()
          self.idTrans.setText(unicode(query.value(0).toString()))
          self.idPlg.setText(unicode(query.value(1).toString()))
          self.noDok.setText(unicode(query.value(2).toString()))
          self.tglDok.setDate(query.value(3).toDate())
          self.disetor.setText(unicode(query.value(4).toString()))
          self.totalRp.setText(unicode(query.value(5).toString()))
          self.poin.setText(unicode(query.value(6).toString()))
          self.ket.setText(unicode(query.value(7).toString()))
          self.auditUser.setText(unicode(query.value(8).toString()))
          self.auditTime.setDateTime(query.value(9).toDateTime())
          if unicode(query.value(11).toString()) == "CIB":
              self.tipeKartu.setCurrentIndex(1)
          self.noKartu.setText(unicode(query.value(12).toString()))
          self.nama.setText(unicode(query.value(14).toString()))
          self.noMmc.setText(unicode(query.value(15).toString()))
          self.telp.setText(unicode(query.value(16).toString()))
          self.alamat.setText(unicode(query.value(17).toString()))          
          if unicode(query.value(13).toString()) == "EMS":
              self.jenisToko.setCurrentIndex(1)

  def idBaru(self):
      noAkhir = 0
      query = QSqlQuery(self.db)
      kode = "TRA"
      per = self.util.getServerToday().date().toString("MMyy")
      self.idModel.setFilter("kode_no = '"+kode+"' and periode = '"+per+"'")
      self.idModel.select()      
      class DatabaseError(Exception): pass
      rback = False
      try:
          if not QSqlDatabase.database().transaction():
              raise DatabaseError
          rback = True
          if self.idModel.rowCount() == 1:
              record = self.idModel.record(0)
              noAkhir = record.value(2).toInt()[0]
              noAkhir += 1
              self.idModel.setData(self.idModel.index(0, 2), QVariant(noAkhir))
          else:
              self.idModel.insertRow(0)
              self.idModel.setData(self.idModel.index(0, 0), QVariant(kode))
              self.idModel.setData(self.idModel.index(0, 1), QVariant("transaksi"))
              self.idModel.setData(self.idModel.index(0, 2), QVariant("1"))
              self.idModel.setData(self.idModel.index(0, 3), QVariant(per))
              self.idModel.setData(self.idModel.index(0, 4), QVariant(""))
              noAkhir = 1
          self.idModel.submitAll()
          if not QSqlDatabase.database().commit():
            raise DatabaseError
          rback = False
      finally:
          if rback:
              if not QSqlDatabase.database().rollback():
                  raise DatabaseError
      id = kode+per+"0"*(6 - len(str(noAkhir)))+str(noAkhir)
      return id
      
  def dokBaru(self):
      noAkhir = 0
      query = QSqlQuery(self.db)
      kode = "TRA_NO_DOK"
      per = self.util.getServerToday().date().toString("MMyy")
      self.idModel.setFilter("kode_no = '"+kode+"' and periode = '"+per+"'")
      self.idModel.select()      
      class DatabaseError(Exception): pass
      rback = False
      try:
          if not QSqlDatabase.database().transaction():
              raise DatabaseError
          rback = True
          if self.idModel.rowCount() == 1:
              record = self.idModel.record(0)
              noAkhir = record.value(2).toInt()[0]
              noAkhir += 1
              self.idModel.setData(self.idModel.index(0, 2), QVariant(noAkhir))
          else:
              self.idModel.insertRow(0)
              self.idModel.setData(self.idModel.index(0, 0), QVariant(kode))
              self.idModel.setData(self.idModel.index(0, 1), QVariant("transaksi"))
              self.idModel.setData(self.idModel.index(0, 2), QVariant("1"))
              self.idModel.setData(self.idModel.index(0, 3), QVariant(per))
              self.idModel.setData(self.idModel.index(0, 4), QVariant(""))
              noAkhir = 1
          self.idModel.submitAll()
          if not QSqlDatabase.database().commit():
            raise DatabaseError
          rback = False
      finally:
          if rback:
              if not QSqlDatabase.database().rollback():
                  raise DatabaseError
      id = "0"*(4 - len(str(noAkhir)))+str(noAkhir)+"/TRA/MMC/"+per.left(2)+"/"+per.right(2)
      return id
      
  def hitungTotal(self):
      totBrs = self.detModel.rowCount()
      jum = 0
      for i in range(totBrs):
          record = self.detModel.record(i)
          jum += record.value(JUMLAH).toDouble()[0]
      self.totalRp.setText(str(jum))
#      hitung poin
      rpPoin = 50000
      if self.jenisToko.currentText() == "EMS":
          rpPoin = 200000
      totPoin = 0
      if jum != 0:
          totPoin = floor(jum/rpPoin)
      if self.tipeKartu.currentText() == "CIB":
         totPoin = totPoin*2
      self.poin.setText(str(totPoin))
      
  def validasi(self):
      valid = True
      if self.nama.text().isEmpty():
          QMessageBox.warning(self, "Transaksi","Data yang diinput tidak valid / Kolom kosong.")
          valid = False
      
      totBrs = self.detModel.rowCount()
      for i in range(totBrs):
          kwit = self.detModel.record(i).value(2).toString()
          if kwit.isEmpty():
              QMessageBox.warning(self, "Transaksi Detail","Kolom kwitansi harus diisi")
              return False
          toko = self.detModel.record(i).value(3).toString()
          if toko.isEmpty():
              QMessageBox.warning(self, "Transaksi Detail","Kolom toko harus diisi")
              return False
      
      return valid


class DetailDelegate(QSqlRelationalDelegate):
    def __init__(self, parent=None):
        super(DetailDelegate, self).__init__(parent)
        
    def paint(self, painter, option, index):
        myoption = QStyleOptionViewItem(option)
        if index.column() == JUMLAH:
            myoption.displayAlignment |= Qt.AlignRight|Qt.AlignVCenter
        QSqlRelationalDelegate.paint(self, painter, myoption, index)
            
if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    form = PelangganEdit()
    form.show()
    app.exec_()
